From e808fe9ad9d44c4d3b3b88a13fb805caaea0ddb3 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 7 Feb 2006 19:16:11 +0100 Subject: [PATCH] Since USER_PTRS_PER_PGD depends on TASK_SIZE and thus on the current thread, it must not be used in code that can be called in the context switch path (otherwise the 32-bitness of the outgoing task is used here rather then the 32-bitness of the incoming one, possibly resulting in large parts of the page tables not getting converted to read-only). Signed-off-by: Jan Beulich --- linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c b/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c index dacbeb23ee..a39d4ab23c 100644 --- a/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c +++ b/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c @@ -40,7 +40,14 @@ static void mm_walk(struct mm_struct *mm, pgprot_t flags) int g,u,m; pgd = mm->pgd; - for (g = 0; g <= USER_PTRS_PER_PGD; g++, pgd++) { + /* + * Cannot iterate up to USER_PTRS_PER_PGD as these pagetables may not + * be the 'current' task's pagetables (e.g., current may be 32-bit, + * but the pagetables may be for a 64-bit task). + * Subtracting 1 from TASK_SIZE64 means the loop limit is correct + * regardless of whether TASK_SIZE64 is a multiple of PGDIR_SIZE. + */ + for (g = 0; g <= ((TASK_SIZE64-1) / PGDIR_SIZE); g++, pgd++) { if (pgd_none(*pgd)) continue; pud = pud_offset(pgd, 0); -- 2.30.2